home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- from: mark%zok@sj.ate.slb.com (Mark W. Snitily)
- subject: v10i079: ppmtoxpm -- new pbmplus utility
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 10, Issue 79
- Submitted-by: mark%zok@sj.ate.slb.com (Mark W. Snitily)
- Archive-name: ppmtoxpm
-
- This is a program that converts images from the ppm (portable pixmap)
- format to the XPM format. See XPM.README and ppmtoxpm.1 for details.
-
- -- Mark
-
- Mark W. Snitily Consulting Services:
- 894 Brookgrove Lane Graphics, Operating Systems, Compilers
- Cupertino, CA 95014 (408) 252-0456
- mark@zok.uucp
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: XPM.README ppmtoxpm.1 ppmtoxpm.c
- # Wrapped by mark@zok on Sun Feb 18 15:57:59 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'XPM.README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'XPM.README'\"
- else
- echo shar: Extracting \"'XPM.README'\" \(4438 characters\)
- sed "s/^X//" >'XPM.README' <<'END_OF_FILE'
- XMost of you are familiar with Jef Poskanzer's pbmplus utilities.
- XFor those of you who are not, they are a wonderful collection of
- Xroutines which transform images from one format to another. This
- Xpackage is distributed on the X11R4 contrib tape and can be found
- Xon many archive sites.
- X
- XA relatively new format is XPM whose origins can be traced back to the
- Xpeople at Groupe Bull -- the same wonderful folks who brought you the
- Xgwm window manager.
- X
- XThis article contains the source and man page for a "ppmtoxpm" tool
- Xwhich transforms an image from the ppm (portable pixmap) format, found
- Xin the pbmplus utilities, to the XPM format.
- X
- XXPM is an ASCII based *color* pixmap format. It's similar to the XBM
- Xformat in that it can be #include'd in C source code, or read from a file
- Xat run time. An example is probably worth a thousand words; the X11
- Xbitmap file ".../include/X11/bitmaps/dot" looks like:
- X
- X#define dot_width 16
- X#define dot_height 16
- Xstatic char dot_bits[] = {
- X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xf0, 0x0f, 0xf0, 0x0f,
- X 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf0, 0x0f, 0xf0, 0x0f,
- X 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- X
- XThe same file in XPM format would be:
- X
- X#define dot_format 1
- X#define dot_width 16
- X#define dot_height 16
- X#define dot_ncolors 2
- X#define dot_chars_per_pixel 1
- Xstatic char *dot_colors[] = {
- X "`", "black",
- X "a", "white"
- X};
- Xstatic char *dot_pixels[] = {
- X"aaaaaaaaaaaaaaaa",
- X"aaaaaaaaaaaaaaaa",
- X"aaaaaaaaaaaaaaaa",
- X"aaaaaa````aaaaaa",
- X"aaaa````````aaaa",
- X"aaaa````````aaaa",
- X"aaa``````````aaa",
- X"aaa``````````aaa",
- X"aaa``````````aaa",
- X"aaa``````````aaa",
- X"aaaa````````aaaa",
- X"aaaa````````aaaa",
- X"aaaaaa````aaaaaa",
- X"aaaaaaaaaaaaaaaa",
- X"aaaaaaaaaaaaaaaa",
- X"aaaaaaaaaaaaaaaa"
- X};
- X
- XAlthough the above example only uses two colors, XPM files can have an
- Xarbitrary number of colors. Colors can be specified by using either the
- Xcolor name mnemonics found in the X11 server's RGB database (e.g. "black"),
- Xor the X11 hexadecimal #RGB, ..., #RRRRGGGGBBBB convention.
- X
- XA good example of a program that understands XPM format is "xloadimage"
- X(a.k.a. "xview" and "xsetbg") by Jim Frost (jimf@saber.com). This program
- Xis on the X11R4 contrib tape and has also been posted on comp.sources.x.
- X"xloadimage" requires patchlevel 3 to correctly understand the XPM format.
- XThis patchlevel should be posted on comp.sources.x in the near future. In
- Xthe mean while, you can obtain a patchlevel 3 version of "xloadimage" via
- Xftp from expo.lcs.mit.edu (18.30.0.212) [/contrib/xloadimage.1.03.tar.Z],
- Xor via uucp from zok [/usrX/contrib/xldim103.tar.Z]. (BTW, "xloadimage"
- Xhas also been tested on unusual X11 servers, those that only have 2 or
- X4 bitplanes.)
- X
- XAfter you unshar the ppmtoxpm.c and ppmtoxpm.1 files, place them into your
- X.../pbmplus/ppm directory. The .../pbmplus/ppm/Imakefile can be updated
- Xby applying the following patch:
- X
- X*** Imakefile.org Tue Nov 21 22:24:43 1989
- X--- Imakefile Sun Feb 18 14:34:59 1990
- X***************
- X*** 28,34 ****
- X PORTBINARIES = giftoppm ilbmtoppm imgtoppm mtvtoppm ppmarith ppmconvol \
- X ppmcscale ppmhist ppmquant ppmscale ppmtogif ppmtoilbm \
- X ppmtopgm ppmtops ppmtorast ppmtoxwd qrttoppm rasttoppm \
- X! tgatoppm xwdtoppm
- X MATHBINARIES = ppmpat ppmrotate ppmshear
- X BINARIES = $(PORTBINARIES) $(MATHBINARIES)
- X
- X--- 28,34 ----
- X PORTBINARIES = giftoppm ilbmtoppm imgtoppm mtvtoppm ppmarith ppmconvol \
- X ppmcscale ppmhist ppmquant ppmscale ppmtogif ppmtoilbm \
- X ppmtopgm ppmtops ppmtorast ppmtoxwd qrttoppm rasttoppm \
- X! tgatoppm xwdtoppm ppmtoxpm
- X MATHBINARIES = ppmpat ppmrotate ppmshear
- X BINARIES = $(PORTBINARIES) $(MATHBINARIES)
- X
- X***************
- X*** 36,42 ****
- X ppmconvol.1 ppmcscale.1 ppmhist.1 ppmpat.1 ppmquant.1 \
- X ppmrotate.1 ppmscale.1 ppmshear.1 ppmtogif.1 ppmtoilbm.1 \
- X ppmtopgm.1 ppmtops.1 ppmtorast.1 ppmtoxwd.1 qrttoppm.1 \
- X! rasttoppm.1 tgatoppm.1 xwdtoppm.1
- X MANUALS3 = libppm.3
- X MANUALS5 = ppm.5
- X
- X--- 36,42 ----
- X ppmconvol.1 ppmcscale.1 ppmhist.1 ppmpat.1 ppmquant.1 \
- X ppmrotate.1 ppmscale.1 ppmshear.1 ppmtogif.1 ppmtoilbm.1 \
- X ppmtopgm.1 ppmtops.1 ppmtorast.1 ppmtoxwd.1 qrttoppm.1 \
- X! rasttoppm.1 tgatoppm.1 xwdtoppm.1 ppmtoxpm.1
- X MANUALS3 = libppm.3
- X MANUALS5 = ppm.5
- X
- X
- XEnjoy.
- X
- X-- Mark
- X
- XMark W. Snitily Consulting Services:
- X894 Brookgrove Lane Graphics, Operating Systems, Compilers
- XCupertino, CA 95014 (408) 252-0456
- Xmark@zok.uucp
- END_OF_FILE
- if test 4438 -ne `wc -c <'XPM.README'`; then
- echo shar: \"'XPM.README'\" unpacked with wrong size!
- fi
- # end of 'XPM.README'
- fi
- if test -f 'ppmtoxpm.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ppmtoxpm.1'\"
- else
- echo shar: Extracting \"'ppmtoxpm.1'\" \(2447 characters\)
- sed "s/^X//" >'ppmtoxpm.1' <<'END_OF_FILE'
- X.TH ppmtoxpm 1 "13 February 1990"
- X.SH NAME
- Xppmtoxpm - convert a portable pixmap into an X11 pixmap
- X.SH SYNOPSIS
- Xppmtoxpm [-name <xpmname>] [-rgb <rgb-textfile>] [<ppmfile>]
- X.SH DESCRIPTION
- XReads a portable pixmap as input.
- XProduces X11 pixmap (XPM) as output.
- X.PP
- XThe -name option allows one to specify the prefix string which is printed
- Xin the resulting XPM output. If not specified, will default to the
- Xfilename (without extension) of the <ppmfile> argument.
- XIf -name is not specified and <ppmfile>
- Xis not specified (i.e. piped input), the prefix string will default to
- Xthe string "noname".
- X.PP
- XThe -rgb option allows one to specify an X11 rgb text file for the
- Xlookup of color name mnemonics. This rgb text file is typically the
- X/usr/lib/X11/rgb.txt of the MIT X11 distribution, but any file using the
- Xsame format may be used. When specified and
- Xa RGB value from the ppm input matches a RGB value from the <rgb-textfile>,
- Xthen the corresponding color name mnemonic is printed in the XPM's colormap.
- XIf -rgb is not specified, or if the RGB values don't match, then the color
- Xwill be printed with the #RGB, #RRGGBB, #RRRGGGBBB, or #RRRRGGGGBBBB
- Xhexadecimal format.
- X.PP
- XAll flags can be abbreviated to their shortest unique prefix.
- X.PP
- XFor example, to convert the file "dot" (found in /usr/include/X11/bitmaps),
- Xfrom xbm to xpm one could specify
- X.IP
- Xxbmtopbm dot | ppmtoxpm -name dot
- X.PP
- Xor, with a rgb text file (in the local directory)
- X.IP
- Xxbmtopbm dot | ppmtoxpm -name dot -rgb rgb.txt
- X.SH BUGS
- XAn option to match the closest (rather than exact) color name mnemonic
- Xfrom the rgb text would be a desirable enhancement.
- X.PP
- XTruncation of the least significant bits of a RGB value may result in
- Xnonexact matches when performing color name mnemonic lookups.
- X.SH "SEE ALSO"
- Xppm(5), xloadimage(1) patchlevel 3 by Jim Frost, jimf@saber.com
- X.SH AUTHOR
- XCopyright (C) 1990 by Mark W. Snitily.
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted, provided
- Xthat the above copyright notice appear in all copies and that both that
- Xcopyright notice and this permission notice appear in supporting
- Xdocumentation. This software is provided "as is" without express or
- Ximplied warranty.
- X
- XThis tool was developed for Schlumberger Technologies, ATE Division, and
- Xwith their permission is being made available to the public with the above
- Xcopyright notice and permission notice.
- END_OF_FILE
- if test 2447 -ne `wc -c <'ppmtoxpm.1'`; then
- echo shar: \"'ppmtoxpm.1'\" unpacked with wrong size!
- fi
- # end of 'ppmtoxpm.1'
- fi
- if test -f 'ppmtoxpm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ppmtoxpm.c'\"
- else
- echo shar: Extracting \"'ppmtoxpm.c'\" \(14877 characters\)
- sed "s/^X//" >'ppmtoxpm.c' <<'END_OF_FILE'
- X/* ppmtoxpm.c - read a portable pixmap and produce a X11 pixmap
- X**
- X** Copyright (C) 1990 by Mark W. Snitily
- X**
- X** Permission to use, copy, modify, and distribute this software and its
- X** documentation for any purpose and without fee is hereby granted, provided
- X** that the above copyright notice appear in all copies and that both that
- X** copyright notice and this permission notice appear in supporting
- X** documentation. This software is provided "as is" without express or
- X** implied warranty.
- X**
- X** This tool was developed for Schlumberger Technologies, ATE Division, and
- X** with their permission is being made available to the public with the above
- X** copyright notice and permission notice.
- X**
- X*/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "ppm.h"
- X#include "ppmcmap.h"
- X
- X#ifdef SYSV
- X#include <string.h>
- X#define index strchr
- X#else /*SYSV*/
- X#include <strings.h>
- X#endif /*SYSV*/
- X
- X/* Max number of colors allowed in ppm input. */
- X#define MAXCOLORS 256
- X
- X/* Max number of rgb mnemonics allowed in rgb text file. */
- X#define MAX_RGBNAMES 1024
- X
- X/* Lower bound and upper bound of character-pixels printed in XPM output.
- X Be careful, don't want the character '"' in this range. */
- X/*#define LOW_CHAR '#' <-- minimum ascii character allowed */
- X/*#define HIGH_CHAR '~' <-- maximum ascii character allowed */
- X#define LOW_CHAR '`'
- X#define HIGH_CHAR 'z'
- X
- X#define max(a,b) ((a) > (b) ? (a) : (b))
- X
- Xvoid read_rgb_names(); /* forward reference */
- Xvoid gen_cmap(); /* forward reference */
- X
- Xtypedef struct { /* rgb values and ascii names (from rgb text file) */
- X int r, g, b; /* rgb values, range of 0 -> 65535 */
- X char *name; /* color mnemonic of rgb value */
- X} rgb_names;
- X
- Xtypedef struct { /* character-pixel mapping */
- X char *cixel; /* character string printed for pixel */
- X char *rgbname; /* ascii rgb color, either color mnemonic or #rgb value */
- X} cixel_map;
- X
- Xpixel **pixels;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *ifd;
- X register pixel *pP;
- X int argn, rows, cols, ncolors, row, col, i;
- X pixval maxval; /* pixval == unsigned char or unsigned short */
- X colorhash_table cht;
- X colorhist_vector chv;
- X
- X /* Used for rgb value -> rgb mnemonic mapping */
- X int map_rgb_names = 0;
- X rgb_names rgbn[MAX_RGBNAMES];
- X int rgbn_max;
- X
- X /* Used for rgb value -> character-pixel string mapping */
- X cixel_map cmap[MAXCOLORS];
- X int charspp; /* chars per pixel */
- X
- X char out_name[100], rgb_fname[100], *cp;
- X char *usage = "[-name <xpm-name>] [-rgb <rgb-textfile>] [ppmfile]";
- X
- X pm_progname = argv[0];
- X out_name[0] = rgb_fname[0] = '\0';
- X
- X argn = 1;
- X
- X /* Check for command line options. */
- X while (argn < argc && argv[argn][0] == '-') {
- X
- X /* Case "-", use stdin for input. */
- X if (argv[argn][1] == '\0') break;
- X
- X /* Case "-name <xpm-filename>", get output filename. */
- X if (strncmp(argv[argn], "-name", max(strlen(argv[argn]),2)) == 0) {
- X argn++;
- X if (argn == argc || sscanf(argv[argn], "%s", out_name) != 1)
- X pm_usage(usage);
- X }
- X
- X /* Case "-rgb <rgb-filename>", get rgb mnemonics filename. */
- X else if (strncmp(argv[argn], "-rgb", max(strlen(argv[argn]),2)) == 0) {
- X argn++;
- X if (argn == argc || sscanf(argv[argn], "%s", rgb_fname) != 1)
- X pm_usage(usage);
- X map_rgb_names = 1;
- X }
- X
- X /* Nothing else allowed... */
- X else
- X pm_usage(usage);
- X
- X argn++;
- X }
- X
- X /* Input file specified, open it and set output filename if necessary. */
- X if (argn < argc) {
- X
- X /* Open the input file. */
- X ifd = pm_openr(argv[argn]);
- X
- X /* If output filename not specified, use input filename as default. */
- X if (out_name[0] == '\0') {
- X strcpy(out_name, argv[argn]);
- X if (cp = index(out_name, '.')) *cp = '\0'; /* remove extension */
- X }
- X
- X /* If (1) input file was specified as "-" we're using stdin, or
- X (2) output filename was specified as "-",
- X set output filename to the default. */
- X if (!strcmp(out_name, "-" )) strcpy(out_name, "noname");
- X
- X argn++;
- X }
- X
- X /* No input file specified. Using stdin so set default output filename. */
- X else {
- X ifd = stdin;
- X if (out_name[0] == '\0') strcpy(out_name, "noname");
- X }
- X
- X /* Only 0 or 1 input files allowed. */
- X if (argn != argc) pm_usage(usage);
- X
- X /* "maxval" is the largest value that can be be found in the ppm file.
- X All pixel components are relative to this value. */
- X pixels = ppm_readppm(ifd, &cols, &rows, &maxval);
- X pm_close(ifd);
- X
- X /* Figure out the colormap. */
- X fprintf(stderr, "(Computing colormap..."); fflush(stderr);
- X chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &ncolors);
- X if (chv == (colorhist_vector) 0)
- X pm_error(
- X "too many colors - try running the pixmap through 'ppmquant 256'",
- X 0, 0, 0, 0, 0);
- X fprintf(stderr, " Done. %d colors found.)\n", ncolors);
- X
- X /* Make a hash table for fast color lookup. */
- X cht = ppm_colorhisttocolorhash(chv, ncolors);
- X
- X /* If a rgb text file was specified, read in the rgb mnemonics.
- X Does not return if fatal error occurs. */
- X if (map_rgb_names) read_rgb_names(rgb_fname, rgbn, &rgbn_max);
- X
- X /* Now generate the character-pixel colormap table. */
- X gen_cmap(chv, ncolors, maxval, map_rgb_names, rgbn, rgbn_max,
- X cmap, &charspp);
- X
- X /* Write out the XPM header. */
- X printf("#define %s_format %d\n", out_name, 1);
- X printf("#define %s_width %d\n", out_name, cols);
- X printf("#define %s_height %d\n", out_name, rows);
- X printf("#define %s_ncolors %d\n", out_name, ncolors);
- X printf("#define %s_chars_per_pixel %d\n", out_name, charspp);
- X
- X /* Write out the ascii colormap. */
- X printf("static char *%s_colors[] = {\n", out_name);
- X for (i=0; i<ncolors; i++) {
- X printf(" \"%s\", \"%s\"", cmap[i].cixel, cmap[i].rgbname);
- X if (i != (ncolors - 1)) printf(",\n");
- X else printf("\n");
- X }
- X printf("};\n");
- X
- X /* Write out the ascii character-pixel image. */
- X printf("static char *%s_pixels[] = {\n", out_name);
- X for (row=0; row<rows; row++) {
- X printf("\"");
- X for (col=0, pP=pixels[row]; col<cols; col++, pP++)
- X printf("%s", cmap[ppm_lookupcolor(cht, *pP)].cixel);
- X if (row != (rows - 1)) printf("\",\n");
- X else printf("\"\n");
- X }
- X printf("};\n");
- X
- X exit(0);
- X
- X} /* main */
- X
- X/*---------------------------------------------------------------------------*/
- X/* This routine reads a rgb text file. It stores the rgb values (0->65535)
- X and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the
- X number of entries stored in "rgbn_max". */
- Xvoid read_rgb_names(rgb_fname, rgbn, rgbn_max)
- Xchar *rgb_fname;
- Xrgb_names rgbn[MAX_RGBNAMES];
- Xint *rgbn_max;
- X{
- X FILE *rgbf;
- X int i, items, red, green, blue;
- X char line[512], name[512], *rgbname, *n, *m;
- X
- X /* Open the rgb text file. Abort if error. */
- X if ((rgbf = fopen(rgb_fname, "r")) == NULL)
- X pm_error("error opening rgb text file \"%s\"", rgb_fname, 0, 0, 0, 0);
- X
- X /* Loop reading each line in the file. */
- X for (i=0; fgets(line, sizeof(line), rgbf); i++) {
- X
- X /* Quit if rgb text file is too large. */
- X if (i == MAX_RGBNAMES) {
- X fprintf(stderr,
- X "Too many entries in rgb text file, truncated to %d entries.\n",
- X MAX_RGBNAMES);
- X fflush(stderr);
- X break;
- X }
- X
- X /* Read the line. Skip if bad. */
- X items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
- X if (items != 4) {
- X fprintf(stderr, "rgb text file syntax error on line %d\n", i+1);
- X fflush(stderr);
- X i--;
- X continue;
- X }
- X
- X /* Make sure rgb values are within 0->255 range. Skip if bad. */
- X if (red < 0 || red > 0xFF ||
- X green < 0 || green > 0xFF ||
- X blue < 0 || blue > 0xFF) {
- X fprintf(stderr, "rgb value for \"%s\" out of range, ignoring it\n",
- X name);
- X fflush(stderr);
- X i--;
- X continue;
- X }
- X
- X /* Allocate memory for ascii name. Abort if error. */
- X if (!(rgbname = (char *) malloc(strlen(name)+1)))
- X pm_error("out of memory allocating rgb name", 0, 0, 0, 0, 0);
- X
- X /* Copy string to ascii name and lowercase it. */
- X for (n=name, m=rgbname; *n; n++)
- X *m++ = isupper(*n) ? tolower(*n) : *n;
- X *m = '\0';
- X
- X /* Save the rgb values and ascii name in the array. */
- X rgbn[i].r = red << 8;
- X rgbn[i].g = green << 8;
- X rgbn[i].b = blue << 8;
- X rgbn[i].name = rgbname;
- X }
- X
- X /* Return the max number of rgb names. */
- X *rgbn_max = i-1;
- X
- X fclose(rgbf);
- X
- X} /* read_rgb_names */
- X
- X/*---------------------------------------------------------------------------*/
- X/* Given a number and a base, (base == HIGH_CHAR-LOW_CHAR+1), this routine
- X prints the number into a malloc'ed string and returns it. The length of
- X the string is specified by "digits". The ascii characters of the printed
- X number range from LOW_CHAR to HIGH_CHAR. The string is LOW_CHAR filled,
- X (e.g. if LOW_CHAR==0, HIGH_CHAR==1, digits==5, i=3, routine would return
- X the malloc'ed string "00011"). */
- Xchar *gen_numstr(i, base, digits)
- Xint i, base, digits;
- X{
- X char *str, *p;
- X int d;
- X
- X /* Allocate memory for printed number. Abort if error. */
- X if (!(str = (char *) malloc(digits+1)))
- X pm_error("out of memory", 0, 0, 0, 0, 0);
- X
- X /* Generate characters starting with least significant digit. */
- X p = str + digits;
- X *p-- = '\0'; /* nul terminate string */
- X while (p >= str) {
- X d = i % base;
- X i /= base;
- X *p-- = (char) ((int) LOW_CHAR + d);
- X }
- X
- X return str;
- X
- X} /* gen_numstr */
- X
- X/*---------------------------------------------------------------------------*/
- X/* This routine generates the character-pixel colormap table. */
- Xvoid gen_cmap(chv, ncolors, maxval, map_rgb_names, rgbn, rgbn_max,
- X cmap, charspp)
- X/* input: */
- Xcolorhist_vector chv; /* contains rgb values for colormap */
- Xint ncolors; /* number of entries in colormap */
- Xpixval maxval; /* largest color value, all rgb values relative
- X to this, (pixval == unsigned short) */
- Xint map_rgb_names; /* == 1 if mapping rgb values to rgb mnemonics */
- Xrgb_names rgbn[MAX_RGBNAMES]; /* rgb mnemonics from rgb text file */
- Xint rgbn_max; /* number of rgb mnemonics in table */
- X/* output: */
- Xcixel_map cmap[MAXCOLORS]; /* pixel strings and ascii rgb colors */
- Xint *charspp; /* characters per pixel */
- X{
- X int i, j, base, cpp, mval, red, green, blue, r, g, b, matched;
- X char *str;
- X
- X /* Figure out how many characters per pixel we'll be using. Don't want
- X to be forced to link with libm.a, so using a division loop rather than
- X a log function. */
- X base = (int) HIGH_CHAR - (int) LOW_CHAR + 1;
- X for (cpp=0, j=ncolors; j; cpp++) j /= base;
- X *charspp = cpp;
- X
- X /* Determine how many hex digits we'll be normalizing to if the rgb value
- X doesn't match a color mnemonic. */
- X mval = (int) maxval;
- X if (mval <= 0x000F) mval = 0x000F;
- X else if (mval <= 0x00FF) mval = 0x00FF;
- X else if (mval <= 0x0FFF) mval = 0x0FFF;
- X else mval = 0xFFFF;
- X
- X /* Generate the character-pixel string and the rgb name for each colormap
- X entry. */
- X for (i=0; i<ncolors; i++) {
- X
- X /* The character-pixel string is simply a printed number in base "base"
- X where the digits of the number range from LOW_CHAR to HIGH_CHAR and
- X the printed length of the number is "cpp". */
- X cmap[i].cixel = gen_numstr(i, base, cpp);
- X
- X /* Fetch the rgb value of the current colormap entry. */
- X red = PPM_GETR(chv[i].color);
- X green = PPM_GETG(chv[i].color);
- X blue = PPM_GETB(chv[i].color);
- X
- X /* If the ppm color components are not relative to 15, 255, 4095, 65535,
- X normalize the color components here. */
- X if (mval != (int) maxval) {
- X red = (red * mval) / (int) maxval;
- X green = (green * mval) / (int) maxval;
- X blue = (blue * mval) / (int) maxval;
- X }
- X
- X /* If the "-rgb <rgbfile>" option was specified, attempt to map the
- X rgb value to a color mnemonic. */
- X if (map_rgb_names) {
- X
- X /* The rgb values of the color mnemonics are normalized relative
- X to 255 << 8, (i.e. 0xFF00). [That's how the original MIT code
- X did it, really should have been "v * 65535 / 255" instead of
- X "v << 8", but have to use the same scheme here or else colors
- X won't match...] So, if our rgb values aren't already 16-bit
- X values, need to shift left. */
- X if (mval==0x000F) { r=red << 12; g=green << 12; b=blue << 12;
- X /* Special case hack for "white". */
- X if (0xF000 == r && r == g && g == b)
- X r = g = b = 0xFF00;
- X }
- X else if (mval==0x00FF) { r=red << 8; g=green << 8; b=blue << 8;}
- X else if (mval==0x0FFF) { r=red << 4; g=green << 4; b=blue << 4;}
- X else { r=red; g=green; b=blue; }
- X
- X /* Just perform a dumb linear search over the rgb values of the color
- X mnemonics. One could speed things up by sorting the rgb values
- X and using a binary search, or building a hash table, etc... */
- X for (matched = 0, j=0; j <= rgbn_max; j++)
- X if (r == rgbn[j].r && g == rgbn[j].g && b == rgbn[j].b) {
- X
- X /* Matched. Allocate string, copy mnemonic, and exit. */
- X if (!(str = (char *) malloc(strlen(rgbn[i].name)+1)))
- X pm_error("out of memory", 0, 0, 0, 0, 0);
- X strcpy(str, rgbn[j].name);
- X cmap[i].rgbname = str;
- X matched = 1;
- X break;
- X }
- X if (matched) continue;
- X }
- X
- X /* Either not mapping to color mnemonics, or didn't find a match.
- X Generate an absolute #RGB value string instead. */
- X if (!(str = (char *) malloc(mval == 0x000F ? 5 :
- X mval == 0x00FF ? 8 :
- X mval == 0x0FFF ? 11 :
- X 14)))
- X pm_error("out of memory", 0, 0, 0, 0, 0);
- X
- X sprintf(str, mval == 0x000F ? "#%X%X%X" :
- X mval == 0x00FF ? "#%02X%02X%02X" :
- X mval == 0x0FFF ? "#%03X%03X%03X" :
- X "#%04X%04X%04X", red, green, blue);
- X cmap[i].rgbname = str;
- X }
- X
- X} /* gen_cmap */
- END_OF_FILE
- if test 14877 -ne `wc -c <'ppmtoxpm.c'`; then
- echo shar: \"'ppmtoxpm.c'\" unpacked with wrong size!
- fi
- # end of 'ppmtoxpm.c'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-